package org.springrain.frame.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

/**
 * 正则表达式工具类
 * 
 * @copyright {@link weicms.net}
 * @author springrain<Auto generate>
 * @version 2013-03-19 11:08:15
 * @see org.springrain.frame.util.RegexValidateUtils
 */

public class RegexValidateUtils {

    private RegexValidateUtils() {
        throw new IllegalAccessError("工具类不能实例化");
    }
    // 验证文件后缀
    // Pattern p =
    // Pattern.compile(".+\\.js$",Pattern.CASE_INSENSITIVE);//不区分大小写的,默认只有一个参数时是区分大小写
    // System.out.println(p.matcher("dads.jS").matches());

    /**
     * 对一字符串进行正则验证 验证一个字符串中长度必须大于6位，同时必须包含至少一个字符和一个数值
     * 
     * @param str
     *            待验证的字符串
     * 
     * @return 通过验证时返回null 如果验证出现问题，会返回对应的失败原因
     * @throws Exception
     */
    public static String validateString(String str) throws Exception {
        // 验证长度
        if (validateLength(str) == null) {
            // 验证字符元素
            return isContainNumber(str);
        } else {
            return validateLength(str);
        }

    }

    /**
     * 验证content中必须同时存在数字和字母
     * 
     * @param content
     * @return 通过验证时，返回null 否则返回对应提示
     * @throws Exception
     * 
     */
    public static String isContainNumber(String content) throws Exception {
        String message = "必须包含数字和字母";
        String restring = "^.*(([a-zA-Z]+.*[0-9]+)|([0-9]+.*[a-zA-Z]+)).*$"; // 必须六位以上,包含数字和字母
        Pattern pattern = Pattern.compile(restring);
        if (pattern.matcher(content).matches()) {
            return null;
        }
        return message;
    }

    /**
     * 验证content的长度必须大于等六位
     * 
     * @param content
     * @return 通过验证时，返回null 否则返回对应提示
     * @throws Exception
     */
    public static String validateLength(String content) throws Exception {
        String message = "必须六位以上";
        String restring = "^.{6,}$";
        Pattern pattern = Pattern.compile(restring);
        if (pattern.matcher(content).matches()) {
            return null;
        }
        return message;
    }

    /**
     * 如果字符串url是否以指定的数组的任一字符串结尾
     * 
     * @param url
     *            指定字符串
     * @param noFomat
     *            格式集[".js",".html"] <<主要是用于文件格式的验证，必须以"."开头加后缀名 如： .js >>
     * @return url不是以指定的数组的任一字符串结尾 返回 true 否则返回false
     */
    public static boolean validateUrl(String url, String[] noFomat) {
        // 正则非
        String endStr = "";
        // 为空时返回true
        if (noFomat == null || noFomat.length - 0 == 0 || url == null) {
            return true;
        } else {
            for (int i = 0; i < noFomat.length; i++) {
                if (i - 0 == 0) {
                    endStr = "((\\" + noFomat[i] + ")";
                } else {
                    endStr = endStr + "|(\\" + noFomat[i] + ")";
                }

                if (i - noFomat.length + 1 == 0) {
                    endStr = endStr + ")$";
                }
            }
        }
        // 定义正则
        String reg = "^.*";
        // 验证文件后缀
        // 其中参数意义：不区分大小写的,默认只有一个参数时是区分大小写
        java.util.regex.Pattern p = java.util.regex.Pattern.compile(reg + endStr,
                java.util.regex.Pattern.CASE_INSENSITIVE);
        return !p.matcher(url).matches();
    }

    /**
     * 验证指定的字符串是不是符点型数值
     * 
     * @param value
     *            某指定的字符串
     * @return 字符串符合数值格式时返回true,否则返回false
     */
    public static boolean isFloat(String value) {
        String restring = "^-?(\\d)+((.\\d+)|(\\d)*)$";
        Pattern pattern = Pattern.compile(restring);
        if (pattern.matcher(value).matches()) {
            return true;
        }
        return false;
    }

    /**
     * 获取 order by 开始位置
     * 
     * @param orderbysql
     * @return
     */
    public static int getOrderByIndex(String orderbysql) {
        int index = -1;
        if (StringUtils.isBlank(orderbysql)) {
            return index;
        }
        String regStr = "\\s+(order)\\s+(by)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(orderbysql.toLowerCase());
        if (matcher.find()) {
            index = matcher.start();
        }
        return index;
    }

    /**
     * 获取 group by 开始位置
     * 
     * @param groupbysql
     * @return
     */
    public static int getGroupByIndex(String groupbysql) {
        int index = -1;
        if (StringUtils.isBlank(groupbysql)) {
            return index;
        }
        String regStr = "\\s+(group)\\s+(by)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(groupbysql.toLowerCase());
        if (matcher.find()) {
            index = matcher.start();
        }
        return index;
    }

    /**
     * 获取 group by 开始位置
     * 
     * @param sql
     * @return
     */
    public static int getFromIndex(String sql) {
        int index = -1;
        if (StringUtils.isBlank(sql)) {
            return index;
        }

        String s = replaceFrom(sql).toLowerCase();

        int startIndex = s.indexOf(" from ");
        int lastIndex = s.lastIndexOf(" from ");
        if (startIndex - lastIndex != 0) {
            return index;
        }
        index = startIndex;
        return index;
    }

    /**
     * 去掉无用的 from
     * 
     * @param str
     * @return
     */
    private static String replaceFrom(String str) {
        Pattern pt = Pattern.compile("\\(([\\s\\S]+?)\\)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pt.matcher(str);
        while (matcher.find()) {
            String group = matcher.group(1);
            String t1 = group.toLowerCase().replace(" from ", " abcd ");
            str = str.replace(group, t1);
        }
        return str;
    }

    public static void main(String[] args) {
        // System.out.println(RegexValidateUtils.isFloat("-012416545.000"));
        String countSql = "select 1,(select id from ddddd) FROM abc1 where 1=1  and faa id in (select id from abc2)  distinct a order by   ";

        int order_int = getOrderByIndex(countSql);
        if (order_int > 1) {
            countSql = countSql.substring(0, order_int);
        }

        /**
         * 特殊关键字过滤, distinct ,union ,group by
         */
        if (countSql.toLowerCase().indexOf(" distinct ") > -1 || countSql.toLowerCase().indexOf(" union ") > -1
                || RegexValidateUtils.getGroupByIndex(countSql) > -1) {
            countSql = "SELECT count(*)  frame_row_count FROM (" + countSql + ") temp_frame_noob_table_name WHERE 1=1 ";
        } else {
            int fromIndex = RegexValidateUtils.getFromIndex(countSql);
            if (fromIndex > -1) {
                countSql = "SELECT COUNT(*) " + countSql.substring(fromIndex);
            } else {
                countSql = "SELECT count(*)  frame_row_count FROM (" + countSql
                        + ") temp_frame_noob_table_name WHERE 1=1 ";
            }

        }

        // System.out.println(countSql);

    }
}
